package com.locker.modules.sys.license;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 与二维码门禁的tcp协议中各种接收数据发送数据的加密解密处理
 */
public class TcpDataHandle {
    private static String key = "IR8cQ9wzm46NJ81RSWN9FjOPqdWruVls";
    private static String iv ="szFz2pZsy3bAqKJy";

    /**
     * aes256加密
     * @param data 加密数据
     * @return
     */
    public static String encrypt(String data){
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] raw = key.getBytes();
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw,"AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivParameterSpec);
            byte[] encryted = cipher.doFinal(data.getBytes("UTF-8"));
            byte[] ivByte = new byte[16];
            ivByte = iv.getBytes("utf-8");
            byte[] revByte = new byte[encryted.length+16];
            System.arraycopy(ivByte,0,revByte,0,ivByte.length);
            System.arraycopy(encryted,0,revByte,ivByte.length,encryted.length);
            return new BASE64Encoder().encode(revByte);
        } catch (NoSuchAlgorithmException e) {
            throw Exceptions.unchecked(e);
        } catch (NoSuchPaddingException e) {
            throw Exceptions.unchecked(e);
        } catch (InvalidKeyException e) {
            throw Exceptions.unchecked(e);
        } catch (InvalidAlgorithmParameterException e) {
            throw Exceptions.unchecked(e);
        } catch (IllegalBlockSizeException e) {
            throw Exceptions.unchecked(e);
        } catch (BadPaddingException e) {
            throw Exceptions.unchecked(e);
        } catch (UnsupportedEncodingException e) {
            throw Exceptions.unchecked(e);
        }
    }

    /**
     * aes256解密
     * @param sSrc        解密字符串
     * @return
     */
    public static String decrypt(String sSrc){
        try {
            byte[] raw = key.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original,"utf-8");
            return originalString;
        } catch (UnsupportedEncodingException e) {
            throw Exceptions.unchecked(e);
        } catch (IOException e) {
            throw Exceptions.unchecked(e);
        } catch (NoSuchAlgorithmException e) {
            throw Exceptions.unchecked(e);
        } catch (InvalidKeyException e) {
            throw Exceptions.unchecked(e);
        } catch (InvalidAlgorithmParameterException e) {
            throw Exceptions.unchecked(e);
        } catch (NoSuchPaddingException e) {
            throw Exceptions.unchecked(e);
        } catch (BadPaddingException e) {
            throw Exceptions.unchecked(e);
        } catch (IllegalBlockSizeException e) {
            throw Exceptions.unchecked(e);
        }
    }

    /**
     * sha1加密
     * @param str
     * @return
     */
    public static String getSha1(String str){
        char hexDigits[] = {'0','1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("utf-8"));
            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j*2];
            int k = 0;
            for (int i = 0;i<j;i++){
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0>>>4&0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 将byte数组转化成int类型数据
     * @param bytes
     * @return
     */
    public static int bytes2Int(byte[] bytes){
        int value=0;
        value = ((bytes[0] & 0xff)<<24)|
                ((bytes[1] & 0xff)<<16)|
                ((bytes[2] & 0xff)<<8)|
                (bytes[3] & 0xff);
        return value;
    }

    /**
     * 将int类型数据转化成byte数组
     * @param value
     * @return
     */
    public static byte[] int2Byte(int value){
        byte[] src = new byte[4];
        src[0] = (byte) ((value>>24) & 0xFF);
        src[1] = (byte) ((value>>16) & 0xFF);
        src[2] = (byte) ((value>>8) & 0xFF);
        src[3] = (byte) (value & 0xFF);
        return src;
    }

    /**
     * 拼接返回给二维码门禁的字符串并转化成byte数组
     * @param scmd
     * @param msgId
     * @param deviceId
     * @param data
     * @param sign
     * @return
     * @throws UnsupportedEncodingException
     */
    public static byte[] returnDataSplice(String scmd,String msgId,String deviceId,String data,String sign) throws UnsupportedEncodingException {
        StringBuffer sb = new StringBuffer();
        sb.append("proVer=1.0&appId=10013&appVer=11&scmd=")
            .append(scmd)
            .append("&msgId=")
            .append(msgId)
            .append("&deviceId=")
            .append(deviceId)
            .append("&repush=true&data=")
            .append(data)
            .append("&sign=")
            .append(sign);
        byte[] dataByte = sb.toString().getBytes("utf-8");
        byte[] lenByte = TcpDataHandle.int2Byte(dataByte.length);
        byte[] retByte = new byte[dataByte.length+4];
        System.arraycopy(lenByte,0,retByte,0,lenByte.length);
        System.arraycopy(dataByte,0,retByte,lenByte.length,dataByte.length);
//        System.out.println("发送的数据为"+new String(retByte,0,4));
        return retByte;
    }
}
